package service

import (
	"fmt"
	"ginchat/models"
	"ginchat/utils"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

// GetUserList
// @Summary 用户列表
// @Tags 用户模块
// @Success 200 {string} json{"code","message"}
// @Router /user/getUserList [get]
func GetUserList(c *gin.Context) {
	// data := make([]*models.UserBasic, 10)
	data := models.GetUserList()
	c.JSON(http.StatusOK, gin.H{
		"code":    0, // 0成功, -1失败
		"message": "查询成功",
		"data":    data,
	})
}

// FindUserByNameAndPwd
// @Summary 用户登录
// @Tags 用户模块
// @Param name formData string false "用户名"
// @Param password formData string false "密码"
// @Success 200 {string} json{"code","message"}
// @Router /user/findUserByNameAndPwd [post]
func FindUserByNameAndPwd(c *gin.Context) {
	data := models.UserBasic{}
	name := c.PostForm("name")
	password := c.PostForm("password")
	user := models.FindUserByName(name)
	if user.Name == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "该用户不存在",
			"data":    data,
		})
		return
	}
	flag := utils.ValidPassword(password, user.Salt, user.Password)
	if !flag {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "密码不正确",
			"data":    data,
		})
		return
	}
	password = utils.MakePassword(password, user.Salt)
	data = models.FindUserByNameAndPwd(name, password)
	c.JSON(http.StatusOK, gin.H{
		"code":    0, // 0成功, -1失败
		"message": "登录成功",
		"data":    data,
	})
}

// CreateUser
// @Summary 新增用户
// @Tags 用户模块
// @Param name formData string false "用户名"
// @Param password formData string false "密码"
// @Param checkPassword formData string false "确认密码"
// @Param phone formData string false "手机号"
// @Param email formData string false "邮箱"
// @Success 200 {string} json{"code","message"}
// @Router /user/createUser [post]
func CreateUser(c *gin.Context) {
	user := models.UserBasic{}
	user.Name = c.PostForm("name")
	password := c.PostForm("password")
	checkPassword := c.PostForm("checkPassword")
	user.Phone = c.PostForm("phone")
	user.Email = c.PostForm("email")
	if user.Name == "" || password == "" || checkPassword == "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "用户名或者密码为空",
			"data":    nil,
		})
		return
	}
	if password != checkPassword {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "两次密码不一致",
			"data":    nil,
		})
		return
	} else {
		// 混合盐值加密
		salt := fmt.Sprintf("%06d", rand.Int31())
		user.Salt = salt
		user.Password = utils.MakePassword(password, salt)
	}

	_, err := govalidator.ValidateStruct(user)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "关键参数不匹配",
			"data":    nil,
		})
		return
	}

	// 数据库比对
	findName := models.FindUserByName(user.Name)
	if findName.Name != "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "用户名已被注册",
			"data":    nil,
		})
		return
	}
	findPhone := models.FindUserByPhone(user.Phone)
	if findPhone.Phone != "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "手机号已被注册",
			"data":    nil,
		})
		return
	}
	findEmail := models.FindUserByEmail(user.Email)
	if findEmail.Email != "" {
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "邮箱已被注册",
			"data":    nil,
		})
		return
	}

	models.CreateUser(user)
	c.JSON(http.StatusOK, gin.H{
		"code":    0, // 0成功, -1失败
		"message": "新增用户成功",
		"data":    user,
	})
}

// DeleteUser
// @Summary 删除用户
// @Tags 用户模块
// @Param id query string false "id"
// @Success 200 {string} json{"code","message"}
// @Router /user/deleteUser [get]
func DeleteUser(c *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(c.Query("id"))
	user.ID = uint(id)
	models.DeleteUser(user)
	c.JSON(http.StatusOK, gin.H{
		"code":    0, // 0成功, -1失败
		"message": "删除用户成功",
		"data":    user,
	})
}

// UpdateUser
// @Summary 修改用户
// @Tags 用户模块
// @Param id formData string false "id"
// @Param name formData string false "name"
// @Param password formData string false "password"
// @Param phone formData string false "phone"
// @Param email formData string false "email"
// @Success 200 {string} json{"code","message"}
// @Router /user/updateUser [post]
func UpdateUser(c *gin.Context) {
	user := models.UserBasic{}
	id, _ := strconv.Atoi(c.PostForm("id"))
	user.ID = uint(id)
	user.Name = c.PostForm("name")
	user.Password = c.PostForm("password")
	user.Phone = c.PostForm("phone")
	user.Email = c.PostForm("email")
	_, err := govalidator.ValidateStruct(user)
	if err != nil {
		fmt.Println(err)
		c.JSON(http.StatusBadRequest, gin.H{
			"code":    -1, // 0成功, -1失败
			"message": "修改参数不匹配",
			"data":    nil,
		})
	} else {
		models.UpdateUser(user)
		c.JSON(http.StatusOK, gin.H{
			"code":    0, // 0成功, -1失败
			"message": "修改用户成功",
			"data":    user,
		})
	}
}

// 防止跨域站点伪造请求
var upGrade = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		return true
	},
}

func SendMsg(c *gin.Context) {
	ws, err := upGrade.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer func(ws *websocket.Conn) {
		err = ws.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(ws)
	MsgHandler(ws, c)
}
func MsgHandler(ws *websocket.Conn, c *gin.Context) {
	msg, err := utils.Subscribe(c, utils.PublishKey)
	if err != nil {
		fmt.Println(err)
	}
	tm := time.Now().Format("2022-12-16 15:40:00")
	m := fmt.Sprintf("[ws][%s]:%s", tm, msg)
	err = ws.WriteMessage(1, []byte(m))
	if err != nil {
		fmt.Println(err)
	}
}

func SendUserMsg(c *gin.Context) {
	models.Chat(c.Writer, c.Request)
}

// SearchFriends
// @Summary 查找好友
// @Tags 用户模块
// @Param userId formData string false "userId"
// @Success 200 {string} json{"code","message"}
// @Router /user/updateUser [post]
func SearchFriends(c *gin.Context) {
	id, _ := strconv.Atoi(c.PostForm("userId"))
	users := models.SearchFriend(uint(id))
	utils.RespOKList(c.Writer, users, len(users))
}

// LoadCommunity
// @Summary 加载群列表
// @Tags 用户模块
// @Param ownerId formData string false "ownerId"
// @Success 200 {string} json{"code","message"}
// @Router /contact/loadcommunity [post]
func LoadCommunity(c *gin.Context) {
	ownerId, _ := strconv.Atoi(c.Request.FormValue("ownerId"))
	//	name := c.Request.FormValue("name")
	data, msg := models.LoadCommunity(uint(ownerId))
	if len(data) != 0 {
		utils.RespList(c.Writer, 0, data, msg)
	} else {
		utils.RespFail(c.Writer, msg)
	}
}

func RedisMsg(c *gin.Context) {
	userIdA, _ := strconv.Atoi(c.PostForm("userIdA"))
	userIdB, _ := strconv.Atoi(c.PostForm("userIdB"))
	start, _ := strconv.Atoi(c.PostForm("start"))
	end, _ := strconv.Atoi(c.PostForm("end"))
	isRev, _ := strconv.ParseBool(c.PostForm("isRev"))
	res := models.RedisMsg(int64(userIdA), int64(userIdB), int64(start), int64(end), isRev)
	utils.RespOKList(c.Writer, "ok", res)
}
